#include "my_hook_chain.h"
#include "my_thread_base.h"

my_hook_chain_t *
my_hook_chain_create()
{
    my_hook_chain_t         *hook_chain;

    hook_chain = my_thread_calloc(sizeof(my_hook_chain_t));
    my_queue_init(&hook_chain->head);

    return hook_chain;
}


// free hook chain and hook_item inside it.
void
my_hook_chain_destroy(my_hook_chain_t *hook_chain)
{
    my_hook_item_t          *item;
    my_queue_t              *q;

    while (!my_queue_empty(&hook_chain->head)) {
        q = my_queue_head(&hook_chain->head);
        item = my_queue_data(q, my_hook_item_t, queue);
        my_queue_remove(q);
        my_thread_free(item);
    }

    my_thread_free(hook_chain);
}


void
my_hook_chain_register(my_hook_chain_t *hook_chain,
    my_hook_handler_pt hook_handler)
{
    my_hook_item_t *hook_item =
        my_thread_calloc(sizeof(my_hook_item_t));
    hook_item->handler = hook_handler;
    my_queue_insert_tail(&hook_chain->head, &hook_item->queue);
}


void
my_hook_chain_exec(my_hook_chain_t *hook_chain, void *data)
{
    my_hook_item_t  *item;
    my_queue_t      *q;

    q = my_queue_head(&hook_chain->head);
    while (q != &hook_chain->head) {
        item = my_queue_data(q, my_hook_item_t, queue);
        item->handler(data);
        q = q->next;
    }
}
